//
// Created by Min on 2021/12/10.
//

#include <fstream>
#include <conio.h>
#include "GameLevelHostile.h"
#include "CheckpointStart.h"
#include "CheckpointEnd.h"

auto showBox = [](Collidable&p) {
    rectangle(p.left(), p.top(), p.right(), p.bottom());
};

GameLevelHostile::GameLevelHostile(): GameLevel(15, 15, 63, R"(F:\workspace\starller\resource\Background\Green.png)"),
                                  trampoline(840, 858)
{
}

void GameLevelHostile::init() {
    GameLevel::init();
    std::ifstream fin(R"(F:\workspace\starller\cfg\GameLevelHostileBlocks.cfg)");

    blocks.clear();
    fruits.clear();
    saws.clear();
    while(!fin.eof()) {
        int x, y; fin>>x>>y;
        blocks.emplace_back(x*Block::height, y*Block::width);
    }
    fin.close();

    std::ifstream fruits_config("F:\\workspace\\starller\\cfg\\GameLevelHostileFruits.cfg");
    while(!fruits_config.eof()) {
        int x, y; fruits_config>>x>>y;
        fruits.emplace_back(x, y);
    }

    for(int i=0; i<10; ++i) {
        saws.emplace_back(300, 300 + 40 * i);
    }
}
void GameLevelHostile::run() {
    GameLevel::run();
}
void GameLevelHostile::render() {
    BeginBatchDraw();
    background.render();
    for(auto &blk : blocks) {
        blk.render();
    }
    for(auto &frt: fruits) {
        frt.render();
    }
    for(auto &saw : saws) {
        saw.render();
    }
    trampoline.render();
    player.render();
//    GameLevel::render();
    static char buf[64];
    RECT r = {0, 0, 600, 800};
    sprintf(buf, "SCORE: %d", score);
    setbkmode(TRANSPARENT);
    //设置文本颜色
    settextcolor(BLUE);
    //设置文本样式
    settextstyle(30, 0, TEXT("consolas"));//字体的宽+字体的高+字体的风格
    drawtext(buf, &r, DT_WORDBREAK);
    ckptStart->render();
    if(fruits.empty()) ckptEnd->render();
    EndBatchDraw();
}
void GameLevelHostile::updateWithInput() {
    if(onLand()) {
        if(player.speedY> 1)printf("%f\n", player.speedY);
        if(player.speedY > 16) gameover();
        player.speedY = 0;
        player.state.switchState(PlayerState::IDLE);
    }
    if (_kbhit()) {
        if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('L')) {
            moveRight();
        }
        else if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('H')) {
            moveLeft();
        }
        if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('J') || GetAsyncKeyState(' ')) {
            jump();
        }
        if(GetAsyncKeyState('F')) {
//            printf("[DEBUG] player at: t:%d r:%d b:%d l:%d x:%d y:%d\n", player.top(), player.right(), player.bottom(), player.left(),
//                   (player.left()+player.right())/2, (player.top()+player.bottom())/2
//            );
            printf("%d %d\n", player.left(), player.top());
        }
    }
}
void GameLevelHostile::updateWithoutInput() {
    if(ckptEnd->animation.triggered == TriggerAnimation::TRIGGERED) {
        success();
    }

    if(player.nextStepUp() < 10) {
        player.speedY = 0;
        player.y = 10;
    }
    if(player.nextStepLeft() < 0) {
        player.speedX = 0;
        player.x = 10;
    }
    if(player.nextStepRight() > width) {
        player.speedX = 0;
        player.x = width - 32;
    }
    if(player.nextStepDown() > height) {
        gameover();
    }
    BeginBatchDraw();
    for(auto &blk : blocks) {
        if(blk.bottom() >= player.bottom() &&
           blk.bottom() - player.bottom()<= 50 ||
           blk.top() <= player.top() &&
           player.top() - blk.top() <= 50) {

            if(blk.left() > player.right() && blk.left() - player.nextStepRight() < 2) {
                if(player.speedX>0)player.speedX = 0;
                showBox(blk);
            }
            if(blk.right() < player.left() && blk.right() > player.nextStepLeft()) {
                if(player.speedX<0)player.speedX = 0;
                showBox(blk);
            }
        }
    }
    showBox(player);
//    showBox(trampoline);
//    showBox(*ckptStart);
//    showBox(*ckptEnd);
    // trampoline
    int vMid = (player.left() + player.right()) / 2;
    int hMid = (player.top() + player.bottom()) / 2;
    if(vMid < trampoline.right() && vMid > trampoline.left() &&
       player.bottom() <= trampoline.bottom() && player.bottom() + 20 >= trampoline.bottom()) {
        player.speedY = -player.speedY - 20;
        player.state.switchState(PlayerState::JUMP);
        trampoline.animation.trigger();
    }
    // Saw
    for(auto & saw : saws) {
//        showBox(saw);
        int points[][2] = {{player.left(), player.top()},{player.left(), player.bottom()}, {player.right(), player.top()}, {player.right(), player.bottom()}};
        for(auto [x, y] : points) {
            if(saw.left() < x && saw.right() > x && saw.top()<y && saw.bottom()>y) {
//                printf("OUCH!!!\n");
                gameover();
//                score -= 10;
            }
        }
    }
    // checkpoint end
    if(fruits.empty() && vMid>ckptEnd->left() && vMid < ckptEnd->right() && hMid > ckptEnd->top() && hMid < ckptEnd->bottom()) {
        ckptEnd->animation.trigger();
    }

    EndBatchDraw();

    for(auto it=fruits.cbegin(), ed=fruits.cend(); it!=ed; ) {
        if (player.canEatFruit(*it)) {
            puts("Fruit Eaten!");
            score ++;
            it = fruits.erase(it);
            if(it == fruits.cend()) break;
        }
        else {
            ++it;
        }
    }
    GameLevel::updateWithoutInput();
}
bool GameLevelHostile::onLand() const {
    for(const auto & blk : blocks) {
        if(blk.left()-15<=player.left() && player.right() <= blk.right()+15 &&
           player.bottom() >= blk.top() && player.bottom() - blk.top() <= 63) {
            return true;
        }
    }
    return false;
}

void GameLevelHostile::gameover() {
    setbkmode(TRANSPARENT);
    score = 0;
    RECT r = {0, 0, width, height};
    drawtext("GAME OVER", &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    system("PAUSE");
    init();
}
